/**
 * 麦克风SDK设备管理模块
 * 负责麦克风设备的枚举、选择和权限管理
 */

/**
 * 设备管理器类
 * 管理麦克风设备列表和权限
 */
export class DeviceManager {
  constructor() {
    this.availableMicrophones = [];
    this.selectedMicrophone = null;
    this.hasPermission = null; // null表示未知，true表示已授权，false表示已拒绝
    this.onDeviceListChange = null;
    this.onPermissionChange = null;
  }

  /**
   * 检查麦克风权限
   * @returns {Promise<boolean>} 是否有麦克风权限
   */
  async checkPermission() {
    try {
      // 尝试获取媒体设备，检查权限
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      
      // 获取成功，表示有权限
      this.hasPermission = true;
      
      // 停止获取的流，我们只是为了检查权限
      stream.getTracks().forEach(track => track.stop());
      
      // 通知权限变化
      if (this.onPermissionChange) {
        this.onPermissionChange(true);
      }
      
      return true;
    } catch (error) {
      // 获取失败，可能是权限被拒绝或其他错误
      console.error('检查麦克风权限失败:', error);
      
      // 根据错误类型判断是否是权限问题
      if (error.name === 'NotAllowedError' || error.name === 'PermissionDeniedError') {
        this.hasPermission = false;
        
        // 通知权限变化
        if (this.onPermissionChange) {
          this.onPermissionChange(false);
        }
      }
      
      return false;
    }
  }

  /**
   * 枚举可用的麦克风设备
   * @returns {Promise<Array>} 可用麦克风设备列表
   */
  async enumerateMicrophones() {
    try {
      // 检查是否支持mediaDevices API
      if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
        console.warn('浏览器不支持设备枚举');
        return [];
      }
      
      // 枚举所有媒体设备
      const devices = await navigator.mediaDevices.enumerateDevices();
      
      // 过滤出麦克风设备
      const microphones = devices.filter(device => device.kind === 'audioinput');
      
      // 更新设备列表
      this.availableMicrophones = microphones.map(device => ({
        deviceId: device.deviceId,
        label: device.label || `麦克风 ${device.deviceId.substr(0, 5)}...`,
        groupId: device.groupId
      }));
      
      // 如果没有选择的麦克风，默认选择第一个
      if (!this.selectedMicrophone && this.availableMicrophones.length > 0) {
        this.selectedMicrophone = this.availableMicrophones[0];
      }
      
      // 通知设备列表变化
      if (this.onDeviceListChange) {
        this.onDeviceListChange(this.availableMicrophones);
      }
      
      return this.availableMicrophones;
    } catch (error) {
      console.error('枚举麦克风设备失败:', error);
      return [];
    }
  }

  /**
   * 选择麦克风设备
   * @param {string} deviceId - 要选择的设备ID
   * @returns {Object|null} 选择的麦克风设备，如果未找到则返回null
   */
  selectMicrophone(deviceId) {
    // 查找指定ID的麦克风
    const microphone = this.availableMicrophones.find(mic => mic.deviceId === deviceId);
    
    if (microphone) {
      this.selectedMicrophone = microphone;
      return microphone;
    }
    
    return null;
  }

  /**
   * 获取当前选择的麦克风设备
   * @returns {Object|null} 当前选择的麦克风设备
   */
  getSelectedMicrophone() {
    return this.selectedMicrophone;
  }

  /**
   * 获取麦克风媒体流
   * @returns {Promise<MediaStream|null>} 麦克风媒体流
   */
  async getMicrophoneStream() {
    try {
      // 检查权限
      if (this.hasPermission === false) {
        console.warn('没有麦克风权限');
        return null;
      }
      
      // 构建媒体约束
      const constraints = {
        audio: true
      };
      
      // 如果有选择的麦克风，指定设备ID
      if (this.selectedMicrophone) {
        constraints.audio = {
          deviceId: { exact: this.selectedMicrophone.deviceId }
        };
      }
      
      // 获取媒体流
      const stream = await navigator.mediaDevices.getUserMedia(constraints);
      
      // 更新权限状态
      this.hasPermission = true;
      
      // 通知权限变化
      if (this.onPermissionChange) {
        this.onPermissionChange(true);
      }
      
      return stream;
    } catch (error) {
      console.error('获取麦克风流失败:', error);
      
      // 如果是权限问题，更新权限状态
      if (error.name === 'NotAllowedError' || error.name === 'PermissionDeniedError') {
        this.hasPermission = false;
        
        // 通知权限变化
        if (this.onPermissionChange) {
          this.onPermissionChange(false);
        }
      }
      
      return null;
    }
  }
}

// 导出单例实例
const deviceManager = new DeviceManager();
export default deviceManager; 